package com.wgo.bpot.server.servicewrapper;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import com.wgo.bpot.client.servicerequest.RemoteServicesFactory;
import com.wgo.bpot.client.servicerequest.ServiceRequestor;
import com.wgo.bpot.common.transport.servicefacade.BpotServices;
import com.wgo.bpot.common.transport.servicefacade.RemoteServices;
import com.wgo.bpot.domain.common.AuthenticationHandler;
import com.wgo.bpot.domain.common.UserCredential;
import com.wgo.bpot.domain.common.UserRole;
import com.wgo.bpot.wiring.ServiceAccessor;
import com.wgo.bpot.wiring.ServiceAccessorImpl;
import com.wgo.bpot.wiring.WiringEngine;

public class RemoteServicesFixture {
	private String correctUserName;
	private String correctPassword;
	
	public RemoteServicesFixture(String correctUserName, String correctPassword) {
		this.correctUserName = correctUserName;
		this.correctPassword = correctPassword;
	}

	public BpotServices createBpotServices(final String userName,final String password, final UserRole userRole){
		RemoteServicesFactory remoteServicesFactory = new MyRemoteServicesFactory(userRole);
		RemoteServices stub = remoteServicesFactory.createRemoteServicesStub();
		AuthenticationHandler ah = new AuthenticationHandler() {
			public UserCredential createUserCredential() {
				return new UserCredential(userName,password);
			}
		};
		BpotServices serviceRequestor = ServiceRequestor.createServicesStub(BpotServices.class,new ServiceRequestor(stub,ah));
		return serviceRequestor;
	}

	private class MyRemoteServicesFactory implements RemoteServicesFactory {
		private UserRole userRole;
		
		public MyRemoteServicesFactory(UserRole userRole) {
			this.userRole = userRole;
		}

		public RemoteServices createRemoteServicesStub() {
			return new DummyRemoteServices(createWiring(),RemoteServicesFixture.this.correctUserName,RemoteServicesFixture.this.correctPassword,userRole);
		}

		private WiringEngine<? extends ServiceAccessor> createWiring() {
			WiringEngine<ServiceAccessor> we = new WiringEngine<ServiceAccessor>(){
				public ServiceAccessor getServiceAccessor(Object client) {
					return getServiceAccessor();
				}
				public ServiceAccessor getServiceAccessor() {
					return new ServiceAccessorImpl();
				}
			};
			return we;
		}

        public BpotServices createServices() {
            // TODO Auto-generated method stub
            return null;
        }
	}
	
	@SuppressWarnings({ "unused", "unchecked" })
    private static <D> D createProxy(Class<D> c){
		return (D)Proxy.newProxyInstance(ServiceCallTest.class.getClassLoader(), new Class[]{c}, new InvocationHandler(){
			public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
				return null;
			}
		});
	}
	
}

